//
//  NewSMTH.m
//  ViewPoint
//
//  Created by Demiao Lin on 08-10-23.
//  Copyright 2008 Tsinghua. All rights reserved.
//

#import "NewSMTH.h"
#import "Setting.h"
#import "DataStore.h"

@implementation NewSMTH

@synthesize dataStore;

-(id) init{
	if( (self=[super init]) != nil ){
		dataStore = [[DataStore alloc] init];
		settings = [[Setting alloc] init];
	}
	return self;
}

+(NSData*) getContentDataFromURL: (NSString*)url{
    UIApplication *myApp = [ UIApplication sharedApplication ];
	myApp.networkActivityIndicatorVisible = YES;
	
	NSData *theData;
    NSInteger count = 2;
    while(count>0){
        /*
        NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url] 
                                                    cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                timeoutInterval:60.0];
        */
        NSURLRequest *theRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url] 
                                                    cachePolicy:NSURLRequestReturnCacheDataElseLoad
                                                timeoutInterval:60.0];
        NSURLResponse *response;
        NSError *error;
        theData = [NSURLConnection sendSynchronousRequest:theRequest 
                                        returningResponse:&response 
                                                    error:&error];
        if(theData){
            break;
        }
        count -= 1;
    }
	myApp.networkActivityIndicatorVisible = NO;
	return theData;
}

+(NSString*) getContentFromURL: (NSString*)url{
	NSData *theData = [NewSMTH getContentDataFromURL:url];
	NSString *htmlContent = nil;
	if(theData!=nil){
		//NSLog([NSString stringWithFormat:@"Data Length:%d", [theData length]]);
		htmlContent = [[[NSString alloc] initWithData:theData encoding:NSUTF8StringEncoding] autorelease];
	}
	return htmlContent;
}

+(NSString *)stringWithURL:(NSString *)url {
	NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:url]
                                                cachePolicy:NSURLRequestReturnCacheDataElseLoad
                                            timeoutInterval:30];
    // Fetch the response
	NSData *urlData;
	NSURLResponse *response;
	NSError *error;

	// Make synchronous request
	urlData = [NSURLConnection sendSynchronousRequest:urlRequest
                                    returningResponse:&response
                                                error:&error];
 	// Construct a String around the Data from the response
    NSString *str = [[[NSString alloc] initWithData:urlData encoding:NSUTF8StringEncoding] autorelease];
	return str;
}

+(NSString*) getPostContentFromBoardId: (NSInteger*)board_id post_id:(NSInteger*)post_id post_type:(NSString*)post_type {
	NSError *theError = NULL;

	NSData *data = [NewSMTH getContentDataFromURL:[NSString stringWithFormat:@"http://%@/vp/post/?board_id=%d&post_id=%d&post_type=%@", IPSMTH_HOST, board_id, post_id, post_type]];
    if(data){
        CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithData:data options:0 error:&theError] autorelease];
        //CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithContentsOfURL:[NSString stringWithFormat:@"http://%@/vp/post/?board_id=%d&post_id=%d&post_type=%@", IPSMTH_HOST, board_id, post_id, post_type]] 
        //                                                                    options:0 
        //                                                                      error:&theError] autorelease];
        
        NSString *content = [[theXMLDocument rootElement] stringValue];
        return content;
    }
    return nil;
    //NSInteger *childCount = (NSInteger *)[[theXMLDocument rootElement] childCount];
    /*
    for (CXMLNode *theNode in [[theXMLDocument rootElement] children]) {
        if([theNode kind] == CXMLTextKind){
            return [theNode stringValue];
        }
    }
    
    return @"";
    */
    //return [NewSMTH getContentFromURL:[NSString stringWithFormat:@"http://%@/vp/post/?board_id=%d&post_id=%d&post_type=%@", IPSMTH_HOST, board_id, post_id, post_type]];
}

-(Board*) getBoardWithName:(NSString*)board_name {
	Board *stored_board = [dataStore getBoardWithName:board_name];
    if(stored_board!=nil){
		return stored_board;
	} else {
		NSError *theError = NULL;
		NSString *url = [NSString stringWithFormat:@"http://%@/vp/boardinfo/?board_name=%@", IPSMTH_HOST, board_name];
		NSData *data = [NewSMTH getContentDataFromURL:url];
        
        CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithData:data options:0 error:&theError] autorelease];
        CXMLElement *theElement = [theXMLDocument rootElement];
        
        NSString *real_board_name = [[theElement attributeForName:@"board_name"] stringValue];
        NSInteger *board_id = (NSInteger *)[[[theElement attributeForName:@"board_id"] stringValue] integerValue];
        NSString *description = [[theElement attributeForName:@"description"] stringValue];
        NSInteger *order = (NSInteger *)[[[theElement attributeForName:@"order"] stringValue] integerValue];
        
        Board *board = [[[Board alloc] initWithName:real_board_name bid:board_id order:order desc:description] autorelease];
        
        [dataStore addBoard:board];
		return board;
	}
}

-(Post*) getPostWithBoardId: (NSInteger*)board_id post_id:(NSInteger*)post_id post_type:(NSString*)post_type {
	[settings refresh];
	NSString *params = @"";
	if([(NSString*)[settings valueForKey:kshow_senderKey] boolValue]){
		params = [params stringByAppendingString:@"&sender"];
	}

	if([(NSString*)[settings valueForKey:kshow_dateKey] boolValue]){
		params = [params stringByAppendingString:@"&date"];
	}

	if([(NSString*)[settings valueForKey:kshow_ipKey] boolValue]){
		params = [params stringByAppendingString:@"&ip"];
	}
	
	if([(NSString*)[settings valueForKey:kshow_titleKey] boolValue]){
		params = [params stringByAppendingString:@"&title"];
	}
	
	if([(NSString*)[settings valueForKey:kshow_referenceKey] boolValue]){
		params = [params stringByAppendingString:@"&ref"];
	}

	if([(NSString*)[settings valueForKey:kshow_attachmentKey] boolValue]){
		params = [params stringByAppendingString:@"&att"];
	}

	if([(NSString*)[settings valueForKey:kshow_signatureKey] boolValue]){
		params = [params stringByAppendingString:@"&sign"];
	}
	
	//NSLog(params);
	//params = @"";
	
	NSError *theError = NULL;
	NSString *url = [NSString stringWithFormat:@"http://%@/vp/post/?board_id=%d&post_id=%d&post_type=%@%@", IPSMTH_HOST, board_id, post_id, post_type, params];
	
	//NSLog(url);
	
	NSData *data = [NewSMTH getContentDataFromURL:url];
    if(data){
        CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithData:data options:0 error:&theError] autorelease];
        //CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithContentsOfURL:url] 
        //                                                                    options:0 
        //                                                                      error:&theError] autorelease];
        
        CXMLElement *theElement = [theXMLDocument rootElement];
        NSString *title = [[theElement attributeForName:@"title"] stringValue];
        NSInteger *thread_id = (NSInteger *)[[[theElement attributeForName:@"thread_id"] stringValue] integerValue];
        NSInteger *pid = (NSInteger *)[[[theElement attributeForName:@"post_id"] stringValue] integerValue];
        NSString *user = [[theElement attributeForName:@"user"] stringValue];
        NSString *date = [[theElement attributeForName:@"date"] stringValue];
        NSInteger *word_count = (NSInteger *)[[[theElement attributeForName:@"word_count"] stringValue] integerValue];
        NSString *tag = [[theElement attributeForName:@"tag"] stringValue];
        
        NSString *content = [[theXMLDocument rootElement] stringValue];
        
        /*
        for (CXMLNode *theNode in [[theXMLDocument rootElement] children]) {
            //if([theNode kind] == CXMLTextKind){
            content = [theNode stringValue];
            break;
            //}
        }
        */

        Post *post = [[[Post alloc] initWithTitle:title tid:thread_id pid:pid user:user tag:tag date:date word_count:word_count] autorelease];
        post.content  = content;
        
        //NSString *css = @"<style>\nbody {padding: 0px; margin: 0px; font-family: Georgia, Tahoma, Verdana, hei; font-size: 20px; -webkit-text-size-adjust: none; background-color: #222; COLOR: #CCCCCC; line-height: 1.5;}\n.title{COLOR: yellow;}\n.ref, .ref br {margin-left: 8px;border-left-width: thin;font-size: 19px;color: gray;}\n.signature, .signature br {margin-right: 2px;font-size: 19px;color: #CC66CC;}\n.head {font-size: 19px;color: gray;}\n.attr {color: #CAFF70;}\n.val {color: gold;}\n</style>";
        //NSString *script = @"<script type='javascript'>function test(){alert('hello! ldmiao!');}</script>";
        //post.content = [NSString stringWithFormat:@"<html><head>%@\n%@</head><body>\n%@\n<br/></body></html>", css, script, content];
        
        return post;
    }
    return nil;
}

-(NSString*) getCssStyle {
    [settings refresh];
    
	NSString *css = (NSString*)[settings valueForKey:kcssKey];
	if(css!=nil){
		NSLog(@"get Css from settings!");
		return css;
	} else {
		NSString *url = [NSString stringWithFormat:@"http://%@/vp/css/?id=%@", IPSMTH_HOST, (NSString*)[settings valueForKey:kstyleKey]];
		css = [NewSMTH getContentFromURL:url];
		if(css!=nil){
			[settings setValue:css forKey:kcssKey];
            [settings persist];
		}
	}
    [settings close];
	return css;
}

-(NSString*) getCssStyleOld {
	[settings refresh];
	
	NSString *show_sender = @"none";
	NSLog([NSString stringWithFormat:@"sender: %@", (NSString*)[settings valueForKey:kshow_senderKey]]);
	if([(NSString*)[settings valueForKey:kshow_senderKey] boolValue]){
		show_sender = @"block";
	}
	NSString *show_date = @"none";
	if([(NSString*)[settings valueForKey:kshow_dateKey] boolValue]){
		show_date = @"block";
	}
	NSString *show_ip = @"none";
	if([(NSString*)[settings valueForKey:kshow_ipKey] boolValue]){
		show_ip = @"block";
	}
	
	NSString *show_title = @"none";
	if([(NSString*)[settings valueForKey:kshow_titleKey] boolValue]){
		show_title = @"block";
	}
	NSString *show_reference = @"none";
	if([(NSString*)[settings valueForKey:kshow_referenceKey] boolValue]){
		show_reference = @"block";
	}
	NSString *show_attachment = @"none";
	if([(NSString*)[settings valueForKey:kshow_attachmentKey] boolValue]){
		show_attachment = @"block";
	}
	NSString *show_signature = @"none";
	if([(NSString*)[settings valueForKey:kshow_signatureKey] boolValue]){
		show_signature = @"block";
	}
	
	//NSString *display = @"block";
	NSString *head_css = [NSString stringWithFormat:@"\n.title {display: %@;}\n.sender {display: %@;}\n.date {display: %@;}\n.ip {display: %@;}\n.attachment {display: %@;}\n.signature, .signature br {display: %@; margin-right: 2px;font-size: 14px;color: #CC66CC;}", show_title, show_sender, show_date, show_ip, show_attachment, show_signature];
	NSString *css = [NSString stringWithFormat:@"<style>\nbody {padding: 0px; margin: 0px; font-family: Georgia, Tahoma, Verdana, hei; font-size: 18px; -webkit-text-size-adjust: none; background-color: #222; COLOR: #CCCCCC; line-height: 1.5;}\n.reference {margin-left: 8px;border-left-width: thin;font-size: 14px;color: gray;}\n.post_info {display: block;font-size: 14px;}\n%@\n.head {font-size: 14px;color: gray;}\n.attr {color: #CAFF70;}\n.val {color: gold;}\n</style>", head_css];
	
	return css;
}

-(NSMutableArray *) getBoards {
    NSError *theError = NULL;

	NSData *data = [NewSMTH getContentDataFromURL:[NSString stringWithFormat:@"http://%@/vp/boards/", IPSMTH_HOST]];
    if(data){
        NSMutableArray *array = [[[NSMutableArray alloc] initWithCapacity:20] autorelease];
        
        CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithData:data options:0 error:&theError] autorelease];
        //CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://%@/vp/boards/", IPSMTH_HOST]] 
        //                                                                    options:0 
        //                                                                      error:&theError] autorelease];
        
        NSArray *theNodes = [theXMLDocument nodesForXPath:@"//board" error:&theError];
        for (CXMLElement *theElement in theNodes) {
            NSString *board_name = [[theElement attributeForName:@"board_name"] stringValue];
            NSInteger *board_id = (NSInteger *)[[[theElement attributeForName:@"board_id"] stringValue] integerValue];
            NSString *description = [[theElement attributeForName:@"description"] stringValue];
            NSInteger *order = (NSInteger *)[[[theElement attributeForName:@"order"] stringValue] integerValue];
            Board *board = [[[Board alloc] initWithName:board_name bid:board_id order:order desc:description] autorelease];
            
            //**********************************************************************
            Board *stored_board = [dataStore getBoardWithName:board_name];
            if(stored_board!=nil){
                [dataStore addBoard:board];
            }
            //**********************************************************************
            
            [array addObject:board];
        }
        return array;
    }
	return nil;
}

-(NSMutableArray *) getTop10Posts {
    NSError *theError = NULL;
	NSData *data = [NewSMTH getContentDataFromURL:[NSString stringWithFormat:@"http://www.newsmth.net/rssi.php?h=%d", 1]];
    
    if(data){
        NSMutableArray *array = [[[NSMutableArray alloc] initWithCapacity:10] autorelease];
        
        CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithData:data options:0 error:&theError] autorelease];
        //CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://www.newsmth.net/rssi.php?h=%d", 1]] 
        //                                                                    options:0 
        //                                                                      error:&theError] autorelease];
        
        //NSString *str = [[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] autorelease];
        //NSLog(str);
        
        NSArray *theNodes = [theXMLDocument nodesForXPath:@"//item" error:&theError];
        //NSLog([NSString stringWithFormat:@"item count: %d", [theNodes count]]);
        for (CXMLElement *theElement in theNodes) {
            CXMLNode *theNode = [theElement firstElementForName:@"title"];
            NSString *title = [theNode stringValue];
            //NSLog(title);
            
            theNode = [theElement firstElementForName:@"link"];
            NSString *link = [theNode stringValue];
            //NSLog(link);
            
            NSRange boardRange = [link rangeOfString:@"board="];
            NSRange tidRange = [link rangeOfString:@"&gid="];
            
            NSRange board_nameRange = NSMakeRange(boardRange.location+boardRange.length, tidRange.location-(boardRange.location+boardRange.length));
            NSRange thread_idRange = NSMakeRange(tidRange.location+tidRange.length, [link length]-(tidRange.location+tidRange.length));
            
            NSString *board_name = [link substringWithRange:board_nameRange];
            Board *board = [self getBoardWithName: board_name];
            NSInteger *board_id = board.bid;
            
            NSInteger *thread_id = (NSInteger*)[[link substringWithRange:thread_idRange] integerValue];
            
            theNode = [theElement firstElementForName:@"author"];
            NSString *user = [theNode stringValue];
            //NSLog(user);
            
            theNode = [theElement firstElementForName:@"pubDate"];
            NSString *date = [theNode stringValue];
            //NSLog(date);
            
            Post *post = [[[Post alloc] initWithTitle:title bname:board_name bid:board_id tid:thread_id user:user date:date] autorelease];
            [array addObject:post];
        }
        return array;
    }
    return nil;
}

-(ArrayAndPageNum *) getPostsWithBoardName:(NSString*)board_name page_num:(NSInteger)page_num {
    NSError *theError = NULL;
    
    NSString *url = [NSString stringWithFormat:@"http://%@/vp/posts/?board_name=%@", IPSMTH_HOST, board_name];
    if(page_num>0){
        url = [NSString stringWithFormat:@"http://%@/vp/posts/?board_name=%@&page_num=%d", IPSMTH_HOST, board_name, page_num];
    }
    


	NSData *data = [NewSMTH getContentDataFromURL:url];
    if(data){
        NSMutableArray *array = [[[NSMutableArray alloc] initWithCapacity:30] autorelease];
        
        CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithData:data options:0 error:&theError] autorelease];
        //CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithContentsOfURL:url] 
        //                                                                    options:0 
        //                                                                      error:&theError] autorelease];
        
        page_num = (NSInteger)[[[[theXMLDocument rootElement] attributeForName:@"page_num"] stringValue] integerValue];
        
        NSArray *theNodes = [theXMLDocument nodesForXPath:@"//post" error:&theError];
        for (CXMLElement *theElement in theNodes) {
            NSString *title = [[theElement attributeForName:@"title"] stringValue];
            NSInteger *thread_id = (NSInteger *)[[[theElement attributeForName:@"thread_id"] stringValue] integerValue];
            NSInteger *post_id = (NSInteger *)[[[theElement attributeForName:@"post_id"] stringValue] integerValue];
            NSString *user = [[theElement attributeForName:@"user"] stringValue];
            NSString *date = [[theElement attributeForName:@"date"] stringValue];
            NSInteger *word_count = (NSInteger *)[[[theElement attributeForName:@"word_count"] stringValue] integerValue];
            NSString *tag = [[theElement attributeForName:@"tag"] stringValue];
            
            Post *post = [[[Post alloc] initWithTitle:title tid:thread_id pid:post_id user:user tag:tag date:date word_count:word_count] autorelease];
            [array addObject:post];
        }
        return [[[ArrayAndPageNum alloc] initWithArray:array page_num:page_num] autorelease];
    }
    return nil;
}


-(ArrayAndPageNum *) getThreadsWithBoardName:(NSString*)board_name page_num:(NSInteger)page_num{
    NSError *theError = NULL;
    
    NSString *url = [NSString stringWithFormat:@"http://%@/vp/threads/?board_name=%@", IPSMTH_HOST, board_name];
    if(page_num>0){
        url = [NSString stringWithFormat:@"http://%@/vp/threads/?board_name=%@&page_num=%d", IPSMTH_HOST, board_name, page_num];
    }
    

	NSData *data = [NewSMTH getContentDataFromURL:url];
    
    if(data){
        NSMutableArray *array = [[[NSMutableArray alloc] initWithCapacity:30] autorelease];
        
        CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithData:data options:0 error:&theError] autorelease];
        //CXMLDocument *theXMLDocument = [[[CXMLDocument alloc] initWithContentsOfURL:url] 
        //                                                                    options:0 
        //                                                                      error:&theError] autorelease];
        
        page_num = [[[[theXMLDocument rootElement] attributeForName:@"page_num"] stringValue] integerValue];
        
        NSArray *theNodes = [theXMLDocument nodesForXPath:@"//thread" error:&theError];
        for (CXMLElement *theElement in theNodes) {
            NSString *title = [[theElement attributeForName:@"title"] stringValue];
            NSInteger *thread_id = (NSInteger *)[[[theElement attributeForName:@"thread_id"] stringValue] integerValue];
             
            Thread *thread = [[[Thread alloc] initWithTitle:title tid:thread_id] autorelease];
            [array addObject:thread];
        }
        
        return [[[ArrayAndPageNum alloc] initWithArray:array page_num:page_num] autorelease];
    }
    return nil;
}

- (void)dealloc {
    [dataStore release];
	[settings release];
    [super dealloc];
}

@end


@implementation Thread

@synthesize title;
@synthesize tid;

-(id) initWithTitle:(NSString*) thread_title 
				tid:(NSInteger*) thread_id{
	if(self==[super init]){
		self.title = thread_title;
		self.tid = thread_id;
	}
	return self;
}

- (void)dealloc {
    [title release];
    [super dealloc];
}

@end

@implementation Board

@synthesize bname;
@synthesize bid;
@synthesize desc;
@synthesize order;

-(id) initWithName:(NSString*) board_name 
			   bid:(NSInteger*) board_id 
			 order:(NSInteger*) board_order
			 desc:(NSString*) board_description{
	if(self==[super init]){
		self.bname = board_name;
		self.bid = board_id;
		self.order = board_order;
		self.desc = board_description;
	}
	return self;
}

-(id) initWithBoardName:(NSString*) board_name 
			        bid:(NSInteger*) board_id{
	if(self==[super init]){
		self.bname = board_name;
		self.bid = board_id;
	}
	return self;
}

- (void)dealloc {
    [bname release];
	[desc release];
    [super dealloc];
}

@end



@implementation Post

@synthesize title;
@synthesize bname;
@synthesize bid;
@synthesize tid;
@synthesize pid;
@synthesize word_count;
@synthesize user;
@synthesize tag;
@synthesize date;
@synthesize content;

-(id) initWithTitle:(NSString*) post_title 
				tid:(NSInteger*) thread_id
                pid:(NSInteger*) post_id
			   user:(NSString*) post_user 
				tag:(NSString*) post_tag 
			   date:(NSString*) post_date 
		 word_count:(NSInteger*) post_word_count {
	if(self==[super init]){
		self.title = post_title;
        self.tid = thread_id;
		self.pid = post_id;
		self.user = post_user;
		self.tag = post_tag;
		self.date = post_date;
		self.word_count = post_word_count;
	}
	return self;
}

-(id) initWithTitle:(NSString*) post_title 
				bid:(NSInteger*) board_id 
				pid:(NSInteger*) post_id 
			   user:(NSString*) post_user 
				tag:(NSString*) post_tag 
			   date:(NSString*) post_date 
		 word_count:(NSInteger*) post_word_count {
	if(self==[super init]){
		self.title = post_title;
		self.bid = board_id;
		self.pid = post_id;
		self.user = post_user;
		self.tag = post_tag;
		self.date = post_date;
		self.word_count = post_word_count;
	}
	return self;
}

-(id) initWithTitle:(NSString*) post_title 
			 bname:(NSString*) board_name 
                bid:(NSInteger*) board_id 
				tid:(NSInteger*) thread_id 
			   user:(NSString*) post_user
			   date:(NSString*) post_date{
	if(self==[super init]){
		self.title = post_title;
        self.bname = board_name;
		self.bid = board_id;
		self.tid = thread_id;
        self.pid = thread_id;
		self.user = post_user;
		self.date = post_date;
	}
	return self;
}

- (void)dealloc {
    [title release];
    [bname release];
	[user release];
	[date release];
	[tag release];
    [super dealloc];
}

@end



@implementation ArrayAndPageNum

@synthesize array;
@synthesize page_num;

-(id) initWithArray:(NSMutableArray*) oneArray
		   page_num:(NSInteger) pagenum{
	if(self==[super init]){
		self.array = oneArray;
		self.page_num = pagenum;
	}
	return self;
}

- (void)dealloc {
    [array release];
    //[pagenum release];
    [super dealloc];
}

@end